package com.kevin.table;

import java.util.List;
import java.util.ListIterator;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.kevin.sql.DataType;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;

public class MDataRowCollection implements List<MDataRow>,Comparator<MDataRow> {
	ArrayList<MDataRow> rowList;
	private MDataTable dataTable;
	private int index = -1, groupID = -1;
    private boolean isAsc = true;
    private int lastIndex = -1;//上一个索引,在多重排序中，如果二次排序遇到相同的值，采用上一个索引字段进行比较
    private boolean lastIsAsc = true;
    private int useLastIndexState = 0;//0未使用,1开启使用,2正在使用
    
	MDataRowCollection(){
		rowList = new ArrayList<MDataRow>(100);
	}
	MDataRowCollection(MDataTable dt){
		rowList = new ArrayList<MDataRow>(100);
		dataTable = dt;
	}
	
	/**
	 * 只读
	 * @return
	 */
	public MDataTable getDataTable() {
		return dataTable;
	}
	
	
	public boolean add(MDataRow dr,Boolean resetState){
		if(resetState){
			
		}
		return rowList.add(dr);
	}
	
	@Override
	public int compare(MDataRow x, MDataRow y)
    {

        // cCount++;
        if (x == y)//自己和自己比，返回0跳出
        {
            return 0;
        }
        int cellIndex = index;
        boolean cellIsAsc = isAsc;
        int cellGroupID = groupID;
        if (useLastIndexState == 1)//出于多重排序的需要这么使用。
        {
            cellIndex = lastIndex;
            cellIsAsc = lastIsAsc;
            useLastIndexState = 2;
            cellGroupID = DataType.getGroup(x.get(cellIndex).getCellstruct().getSqlType());
        }
        else if (useLastIndexState == 2)
        {
            useLastIndexState = 0;
        }
        //Null判断处理
        if (x.get(cellIndex).isNull() && y.get(cellIndex).isNull())
        {
            return 0;
        }
        else if (x.get(cellIndex).isNull())
        {
            return cellIsAsc ? -1 : 1;
        }
        else if (y.get(cellIndex).isNull())
        {
            return cellIsAsc ? 1 : -1;
        }
        Object objAValue = x.get(cellIndex).getValue();
        Object objBValue = y.get(cellIndex).getValue();
        switch (cellGroupID)
        {
            case 1:
            case 3:
                double vA, vB;
                if (cellGroupID == 1)
                {
                	vA = Double.parseDouble(objAValue.toString());
                	vB = Double.parseDouble(objBValue.toString());
                    //vA = (int)objAValue;
                    //vB = (int)objBValue;
                }
                else
                {
                    vA = (boolean)objAValue ? 1 : 0;
                    vB = (boolean)objBValue ? 1 : 0;
                }
                if (vA > vB) { return cellIsAsc ? 1 : -1; }
                else if (vA < vB) { return cellIsAsc ? -1 : 1; }
                else
                {
                    if (lastIndex > -1 && useLastIndexState == 0)
                    {
                        useLastIndexState = 1;//标志为正在使用
                        return compare(x, y);
                    }
                    return 0;
                }
            case 2:
            	Calendar cA = Calendar.getInstance();
            	cA.setTime((Date)objAValue);
            	Calendar cB = Calendar.getInstance();
            	cB.setTime((Date)objBValue);                       	
                return cellIsAsc ? cA.compareTo(cB) : cB.compareTo(cA);
            default:
                //直接性能差一点return cellIsAsc ? Comparer<string>.Default.Compare((string)objAValue, (string)objBValue) : Comparer<string>.Default.Compare((string)objBValue, (string)objAValue);
                if (cellIsAsc)
                {
                    return String.valueOf(objAValue).compareTo(objBValue.toString());
                }
                else
                {
                    return String.valueOf(objBValue).compareTo(objAValue.toString());
                }
        }

    }
	
	
	 public void sort(String orderby)
     {
         if (StringUtils.isEmpty(orderby) || this.size() < 2) { return; }
         orderby = orderby.trim();
         if (orderby.toLowerCase().startsWith("order by"))
         {
             orderby = orderby.substring(9);//去掉order by 前缀
         }
         String[] orderbyList = orderby.split(",");//分隔多个order by 语句
         String[] orderbyItems;

         for (int i = orderbyList.length - 1; i > -1; i--)//反转循环
         {
             if (StringUtils.isEmpty(orderbyList[i]))
             {
                 continue;
             }
             orderbyItems = orderbyList[i].split(StringUtils.SPACE);//分隔

             index = this.get(0).getColumns().indexOf(orderbyItems[0]);
             if (index > -1)
             {
                 isAsc = (orderbyItems.length > 1 && orderbyItems[1].toLowerCase() == "desc") ? false : true;
                 groupID = DataType.getGroup(this.get(0).get(index).getCellstruct().getSqlType());
                 // cCount = 0;
                 Collections.sort(rowList, this);
                 lastIndex = index;
                 lastIsAsc = isAsc;
             }

         }
         index = -1;
         lastIndex = -1;
     }
	 
	 public void removeRange(int fromIndex, int toIndex){
		 rowList.subList(fromIndex, toIndex).clear();
	 }
	@Override
	public boolean add(MDataRow dr) {
		return rowList.add(dr);
	}
	@Override
	public void add(int index, MDataRow element) {
		// TODO Auto-generated method stub
		rowList.add(index, element);
	}
	@Override
	public boolean addAll(Collection<? extends MDataRow> c) {
		// TODO Auto-generated method stub
		return rowList.addAll(c);
	}
	@Override
	public boolean addAll(int index, Collection<? extends MDataRow> c) {
		// TODO Auto-generated method stub
		return rowList.addAll(index, c);
	}
	@Override
	public void clear() {
		// TODO Auto-generated method stub
		rowList.clear();
	}
	@Override
	public boolean contains(Object o) {
		// TODO Auto-generated method stub
		return rowList.contains(o);
	}
	@Override
	public boolean containsAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return rowList.containsAll(c);
	}
	@Override
	public MDataRow get(int index) {
		// TODO Auto-generated method stub
		return rowList.get(index);
	}
	@Override
	public int indexOf(Object o) {
		// TODO Auto-generated method stub
		return rowList.indexOf(o);
	}
	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return rowList.isEmpty();
	}
	@Override
	public Iterator<MDataRow> iterator() {
		// TODO Auto-generated method stub
		return rowList.iterator();
	}
	@Override
	public int lastIndexOf(Object o) {
		// TODO Auto-generated method stub
		return rowList.lastIndexOf(o);
	}
	@Override
	public ListIterator<MDataRow> listIterator() {
		// TODO Auto-generated method stub
		return rowList.listIterator();
	}
	@Override
	public ListIterator<MDataRow> listIterator(int index) {
		// TODO Auto-generated method stub
		return rowList.listIterator(index);
	}
	@Override
	public boolean remove(Object o) {
		// TODO Auto-generated method stub
		return rowList.remove(o);
	}
	@Override
	public MDataRow remove(int index) {
		// TODO Auto-generated method stub
		return rowList.remove(index);
	}
	@Override
	public boolean removeAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return rowList.removeAll(c);
	}
	@Override
	public boolean retainAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return rowList.retainAll(c);
	}
	@Override
	public MDataRow set(int index, MDataRow element) {
		// TODO Auto-generated method stub
		return rowList.set(index, element);
	}
	@Override
	public int size() {
		return rowList.size();
	}
	@Override
	public List<MDataRow> subList(int fromIndex, int toIndex) {
		// TODO Auto-generated method stub
		return rowList.subList(fromIndex, toIndex);
	}
	@Override
	public Object[] toArray() {
		// TODO Auto-generated method stub
		return rowList.toArray();
	}
	@Override
	public <T> T[] toArray(T[] a) {
		// TODO Auto-generated method stub
		return rowList.toArray(a);
	}

	
}
